package com.kaiwukj.android.ufamily.app.base.review;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;

import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

import com.blankj.utilcode.util.AdaptScreenUtils;
import com.blankj.utilcode.util.ScreenUtils;
import com.irozon.sneaker.Sneaker;
import com.kaiwukj.android.mcas.base.delegate.IActivity;
import com.kaiwukj.android.mcas.di.component.AppComponent;
import com.kaiwukj.android.mcas.integration.cache.Cache;
import com.kaiwukj.android.mcas.integration.cache.CacheType;
import com.kaiwukj.android.mcas.integration.lifecycle.ActivityLifecycleable;
import com.kaiwukj.android.mcas.utils.McaUtils;
import com.kaiwukj.android.mcas.utils.UToast;
import com.kaiwukj.android.ufamily.R;
import com.kaiwukj.android.ufamily.app.MyApplication;
import com.kaiwukj.android.ufamily.mvp.http.entity.event.HttpErrorEvent;
import com.kaiwukj.android.ufamily.mvp.http.exception.ApiException;
import com.kaiwukj.android.ufamily.mvp.ui.widget.DefaultDialog;
import com.kaiwukj.android.ufamily.mvp.ui.widget.OkClickListener;
import com.qiniu.android.utils.StringUtils;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.trello.rxlifecycle2.android.ActivityEvent;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

import butterknife.ButterKnife;
import butterknife.Unbinder;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.subjects.BehaviorSubject;
import io.reactivex.subjects.Subject;
import me.yokeyword.fragmentation.ISupportFragment;
import me.yokeyword.fragmentation.SupportActivity;
import me.yokeyword.fragmentation.SupportHelper;
import timber.log.Timber;

/**
 * 完全重构代价太大，还是在已有基础上做优化
 */
public abstract class BaseActivity extends SupportActivity implements IActivity, ActivityLifecycleable {

    public static final int REQUEST_SETTINGS = 100;

    private Unbinder unbinder;

    private final BehaviorSubject<ActivityEvent> mLifecycleSubject = BehaviorSubject.create();
    private Cache<String, Object> mCache;

    private CompositeDisposable mCompositeDisposable;
    private Disposable loadingDisposable;

    protected Context mContext;

    private QMUITipDialog loadingDialog;

    @LayoutRes
    protected abstract int getLayoutId();

    protected abstract void initView(Bundle savedInstanceState);

    protected abstract void initData(Bundle savedInstanceState);

    @SuppressWarnings("unchecked")
    @NonNull
    public Cache<String, Object> provideCache() {
        if (mCache == null) {
            mCache = McaUtils.obtainAppComponentFromContext(this).cacheFactory().build(CacheType.ACTIVITY_CACHE);
        }
        return mCache;
    }

    @NonNull
    @Override
    public Subject<ActivityEvent> provideLifecycleSubject() {
        return mLifecycleSubject;
    }

    @Override
    public void setupActivityComponent(@NonNull AppComponent appComponent) {
    }

    public boolean useEventBus() {
        return true;
    }

    public boolean useLandscape() {
        return false;
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        if (!useLandscape()) {
          /*  if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O && isTranslucentOrFloating()) {
            fixOrientation();
        }*/
            ScreenUtils.setPortrait(this);
        }

        mContext = this;
        super.onCreate(savedInstanceState);

        setContentView(getLayoutId());

        unbinder = ButterKnife.bind(this);
        if (useEventBus() && !EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }
        initView(savedInstanceState);
        initData(savedInstanceState);
    }

    @Override
    public Resources getResources() {
        return AdaptScreenUtils.adaptWidth(super.getResources(), 1080);
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onStop() {
        super.onStop();
        // ZghlMClient.stopService();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        AdaptScreenUtils.closeAdapt(getResources());
        if (loadingDisposable != null && !loadingDisposable.isDisposed())
            loadingDisposable.dispose();
        unSubscribe();
        if (useEventBus() && EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
        if (unbinder != null) {
            unbinder.unbind();
        }
    }

    protected void showLoading(String loadingMsg) {
        subscribe(Observable.just(loadingMsg)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(msg -> showLoading(msg, "请求超时...")));
    }

    protected void showLoading(String loadingMsg, String failedMsg) {
        if (loadingDialog == null) {
            loadingDialog = new QMUITipDialog.Builder(mContext)
                    .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
                    .setTipWord(loadingMsg)
                    .create();
            loadingDialog.setCanceledOnTouchOutside(false);
            loadingDialog.setCancelable(true);
        }

        if (loadingDisposable != null && !loadingDisposable.isDisposed())
            loadingDisposable.dispose();
        loadingDisposable = Observable.timer(25 * 1000, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(aLong -> {
                    if (!isFinishing()) {
                        if (loadingDialog.isShowing()) {
                            loadingDialog.cancel();
                            //showMessage(failedMsg);
                        }
                    }
                });

        loadingDialog.show();
    }

    protected void hideLoading() {
        if (loadingDialog != null && loadingDialog.isShowing()) {
            loadingDialog.cancel();
        }
    }

    protected void showMessage(String msg) {
        if (!TextUtils.isEmpty(msg)) {
            UToast.showShort(getApplicationContext(), msg);
        }
    }

    protected void subscribe(Disposable disposable) {
        if (mCompositeDisposable == null) {
            mCompositeDisposable = new CompositeDisposable();
        }
        mCompositeDisposable.add(disposable);
    }

    protected void unSubscribe() {
        if (mCompositeDisposable != null && !mCompositeDisposable.isDisposed()) {
            mCompositeDisposable.dispose();
        }
    }

    protected MyApplication getApp() {
        return MyApplication.getInstance();
    }

    protected AppComponent getAppComponent() {
        return getApp().getAppComponent();
    }

    @Subscribe
    public void onApiEvent(HttpErrorEvent errorEvent) {
        String message = errorEvent.getErrMsg();
        if (errorEvent.getThrowable() instanceof ApiException) {
            showMessage(message);
        } else {

            Timber.e("Event happened Error" + message);
            if (!StringUtils.isNullOrEmpty(message)) {
                Sneaker.with(this).setTitle(McaUtils.getString(this, R.string.error_happen_current), Color.WHITE)
                        .autoHide(true)
                        .setMessage(message, Color.WHITE)
                        .sneak(ContextCompat.getColor(this, R.color.common_pressed_bg_color));
            }
        }
    }

    /**
     * 得到位于栈顶Fragment
     */
    public ISupportFragment getTopFragment() {
        return SupportHelper.getTopFragment(getSupportFragmentManager());
    }

    /**
     * 获取栈内的fragment对象
     */
    public <T extends ISupportFragment> T findFragment(Class<T> fragmentClass) {
        return SupportHelper.findFragment(getSupportFragmentManager(), fragmentClass);
    }

    private boolean isTranslucentOrFloating() {
        boolean isTranslucentOrFloating = false;
        try {
            int[] styleableRes = (int[]) Class.forName("com.android.internal.R$styleable").getField("Window").get(null);
            final TypedArray ta = obtainStyledAttributes(styleableRes);
            Method m = ActivityInfo.class.getMethod("isTranslucentOrFloating", TypedArray.class);
            m.setAccessible(true);
            isTranslucentOrFloating = (boolean) m.invoke(null, ta);
            m.setAccessible(false);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return isTranslucentOrFloating;
    }

    @Override
    public void setRequestedOrientation(int requestedOrientation) {
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O && isTranslucentOrFloating()) {
            return;
        }

        super.setRequestedOrientation(requestedOrientation);
    }

    private boolean fixOrientation() {
        try {
            Field field = Activity.class.getDeclaredField("mActivityInfo");
            field.setAccessible(true);
            ActivityInfo o = (ActivityInfo) field.get(this);
            o.screenOrientation = -1;
            field.setAccessible(false);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 全透状态栏
     */
    protected void setStatusBarFullTransparent() {
        if (Build.VERSION.SDK_INT >= 21) {//21表示5.0
            Window window = getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
        } else if (Build.VERSION.SDK_INT >= 19) {//19表示4.4
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            //虚拟键盘也透明
            //getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
    }


    /**
     * 如果需要内容紧贴着StatusBar
     * 应该在对应的xml布局文件中，设置根布局fitsSystemWindows=true。
     */
    private View contentViewGroup;

    protected void setFitSystemWindow(boolean fitSystemWindow) {
        if (contentViewGroup == null) {
            contentViewGroup = ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
        }
        contentViewGroup.setFitsSystemWindows(fitSystemWindow);
    }

    @Override
    public boolean useFragment() {
        return false;
    }

    protected void openSettingActivity(final Activity activity, String action, String message) {
        showMessageOKCancel(activity, message, v -> {
            Intent intent = new Intent();
            intent.setAction(action);
            // LogUtils.d("getPackageName(): " + activity.getPackageName());
            Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
            intent.setData(uri);
            activity.startActivityForResult(intent, REQUEST_SETTINGS);
        });
    }

    protected void showMessageOKCancel(final Activity context,
                                       String message,
                                       OkClickListener okListener) {
        DefaultDialog defaultDialog = new DefaultDialog(context);
        defaultDialog.setContent(message);
        defaultDialog.setOkClickListener(okListener);
        defaultDialog.show();
    }

}
